//
// Created by hsj on 2024-1-15.
// semaphore 不能小于0
// 编译： gcc semaphore.c -D_REENTRANT -pthread -o semaphore.out

// 调用sem_init函数时，操作系统将创建信号量对象，此对象中记录着“信号量值”( SemaphoreValue)整数。
// 该值在调用sem_post函数时增1，调用sem_wait函数时减1。
// 但信号量的值不能小于0.
// 因此，在信号量为0的情况下调用sem_wait函数时，调用函数的线程将进人阻塞状态(因为函数未返回)。
// 当然，此时如果有其他线程调用sem_post函数，信号量的值将变为1，而原本阻塞的线程可以将该信号量重新减为0并跳出阻塞状态。
// 实际上就是通过这种特性完成临界区的同步操作。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
void * read(void * arg);
void * accu(void * arg);
static sem_t sem_one;
static sem_t sem_two;
static int num;

int main(int argc, char *argv[] ) {
    pthread_t id_t1, id_t2;
    sem_init(&sem_one, 0, 0);
    sem_init(&sem_two, 0, 1);

    pthread_create(&id_t1, NULL, read, NULL);
    pthread_create(&id_t2, NULL, accu, NULL);

    pthread_join(id_t1, NULL);
    pthread_join(id_t2, NULL);

    sem_destroy(&sem_one);
    sem_destroy(&sem_two);
    return 0;
}
void * read(void * arg) {
    int i;
    for (i = 0; i < 5; i++) {
        fputs("Input num:",stdout);
        sem_wait(&sem_two);//-1
        scanf( "%d",&num) ;
        sem_post(&sem_one);//+1
    }
    return NULL;
}
void * accu(void * arg){
    int sum=0,i;
    for(i=0; i<5; i++){
        sem_wait(&sem_one);//-1
        sum+=num;
        sem_post(&sem_two) ;//+1
    }
    printf("Result: %d \n", sum);
    return NULL ;
}
